package com.battery.minapp.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.battery.common.core.domain.entity.SysDictData;
import com.battery.common.enums.*;
import com.battery.common.utils.BatteryJSONResult;
import com.battery.common.utils.Constants;
import com.battery.common.utils.DateUtils;
import com.battery.common.utils.MapUtils;
import com.battery.common.utils.wx.PayscoreUtils;
import com.battery.minapp.config.WxMaConfiguration;
import com.battery.minapp.redis.lock.RedisCommonLock;
import com.battery.minapp.redis.lock.RedisKeyHelper;
import com.battery.minapp.utils.WsDevUtils;
import com.battery.system.domain.*;
import com.battery.system.domain.VO.*;
import com.battery.system.service.ISysConfigService;
import com.battery.system.service.battery.*;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("/wx")
public class WxApiController {


    private static final Logger logger = LoggerFactory.getLogger(WxApiController.class);


    @Autowired
    private IAppUserService appUserService;


    @Autowired
    private ISysConfigService configService;


    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IUsedService usedService;


    @Autowired
    private IProjectService projectService;


    @Autowired
    private IStoreInstallService storeInstallService;

    @Autowired
    private IOrderService orderService;


    @Autowired
    private IAuthUsedService authUsedService;


    @Autowired
    private IUsedBasicsService usedBasicsService;


    @Autowired
    private Sid sid;

    //  微信支付
    @Autowired
    private WxPayService wxService;


    @Autowired
    private IRefundOrderService refundOrderService;


    @Autowired
    private IStoreService storeService;


    @Autowired
    private IMemberService memberService;

    @Autowired
    private IPartnerService partnerService;


    @Autowired
    private IPartnerInstallService partnerInstallService;


    @Autowired
    private IMerchantInstallService merchantInstallService;


    @Autowired
    private IAdvertService advertService;


    /**
     * 微信用户登陆
     *
     * @param obj
     * @return
     */
    @PostMapping("/login")
    public BatteryJSONResult login(@RequestBody JSONObject obj) {
        String code = obj.getString("code");
        if (StringUtils.isBlank(code)) {
            return BatteryJSONResult.errorMsg("code信息不存在");
        }
        WxMaService wxService = WxMaConfiguration.getMaService(Constants.wxMinAppID);
        WxMaJscode2SessionResult session = null;
        try {
            session = wxService.getUserService().getSessionInfo(code);
            if (session == null) {
                return BatteryJSONResult.errorMsg("code-获取信息失败");
            }
        } catch (WxErrorException e) {
            logger.error(e.getLocalizedMessage());
            return BatteryJSONResult.errorMsg(e.getLocalizedMessage());
        }
        String sessionKey = session.getSessionKey();
        String openid = session.getOpenid();
        // 查询是否存在对应用户
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            appUser = new AppUser();
            appUser.setId(sid.nextShort());
            appUser.setAppUserCode(openid);
            appUser.setUserType(UserTypeEnum.WX.getCode()); // 微信小程序
            appUser.setCreateTime(DateUtils.getNowDate());
            appUser.setSessionKey(sessionKey);
            appUserService.insertSelective(appUser);
        } else {
            AppUser appUserUpdate = new AppUser();
            appUserUpdate.setId(appUser.getId());
            appUser.setSessionKey(sessionKey);
            appUserService.updateByPrimaryKeySelective(appUser);
        }
        JSONObject requestJson = new JSONObject();
        requestJson.put("openid", openid);
        requestJson.put("uid", appUser.getId());
        requestJson.put("sessionKey", sessionKey); // 传递给前端，用来获取到对应的用户信息
        return BatteryJSONResult.ok(requestJson);
    }


    /**
     * 获取用户信息接口
     *
     * @param obj
     * @return
     */
    @PostMapping("/info")
    public BatteryJSONResult info(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String encryptedData = obj.getString("encryptedData");
        String rawData = obj.getString("rawData");
        String sessionKey = obj.getString("sessionKey");
        String iv = obj.getString("iv");
        String signature = obj.getString("signature");

        WxMaService wxService = WxMaConfiguration.getMaService(Constants.wxMinAppID);
        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return BatteryJSONResult.errorMsg("user check failed");
        }
        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        if (userInfo == null) {
            return BatteryJSONResult.errorMsg("get info failed");
        }
        AppUser updateAppUser = new AppUser();
        updateAppUser.setNickName(userInfo.getNickName());
        updateAppUser.setAvatar(userInfo.getAvatarUrl());
        updateAppUser.setProvince(userInfo.getProvince());
        updateAppUser.setCity(userInfo.getCity());
        updateAppUser.setId(appUser.getId());
        if ("0".equals(userInfo.getGender())) {
            updateAppUser.setSex(SexEnum.secret.type);
        } else if ("1".equals(userInfo.getGender())) {
            updateAppUser.setSex(SexEnum.man.type);
        } else {
            updateAppUser.setSex(SexEnum.woman.type);
        }
        appUserService.updateByPrimaryKeySelective(updateAppUser);
        JSONObject requestJson = new JSONObject();
        requestJson.put("uid", appUser.getId());
        return BatteryJSONResult.ok(requestJson);
    }


    /**
     * 获取用户信息接口 提現小程序授權
     *
     * @param obj
     * @return
     */
    @PostMapping("/infoTx")
    public BatteryJSONResult infoTx(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String encryptedData = obj.getString("encryptedData");
        String rawData = obj.getString("rawData");
        String sessionKey = obj.getString("sessionKey");
        String iv = obj.getString("iv");
        String signature = obj.getString("signature");

        WxMaService wxService = WxMaConfiguration.getMaService(Constants.wxMinAppID);
        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return BatteryJSONResult.errorMsg("user check failed");
        }
        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        if (userInfo == null) {
            return BatteryJSONResult.errorMsg("get info failed");
        }

        String accountId = obj.getString("accountId");
        Integer accountType = obj.getInteger("accountType");

        if (accountType != null && StringUtils.isNotBlank(accountId)) {
            if (AccountTypeEnum.PARTNER.getCode().intValue() == accountType.intValue()) {
                // 合作商
                PartnerInstall partnerInstallUpdate = new PartnerInstall();
                partnerInstallUpdate.setPartnerId(accountId);
                partnerInstallUpdate.setAppOpenid(openid);
                partnerInstallService.updateByPrimaryKeySelective(partnerInstallUpdate);

            } else if (AccountTypeEnum.MERCHANT.getCode().intValue() == accountType.intValue()) {
                // 商戶
                MerchantInstall merchantInstallUpdate = new MerchantInstall();
                merchantInstallUpdate.setAppOpenid(openid);
                merchantInstallUpdate.setMerchantId(accountId);
                merchantInstallService.updateByPrimaryKeySelective(merchantInstallUpdate);
            }
        }

        AppUser updateAppUser = new AppUser();
        updateAppUser.setNickName(userInfo.getNickName());
        updateAppUser.setAvatar(userInfo.getAvatarUrl());
        updateAppUser.setProvince(userInfo.getProvince());
        updateAppUser.setCity(userInfo.getCity());
        updateAppUser.setId(appUser.getId());
        if ("0".equals(userInfo.getGender())) {
            updateAppUser.setSex(SexEnum.secret.type);
        } else if ("1".equals(userInfo.getGender())) {
            updateAppUser.setSex(SexEnum.man.type);
        } else {
            updateAppUser.setSex(SexEnum.woman.type);
        }
        appUserService.updateByPrimaryKeySelective(updateAppUser);
        JSONObject requestJson = new JSONObject();
        requestJson.put("uid", appUser.getId());
        return BatteryJSONResult.ok(requestJson);
    }

    /**
     * 更新用户信息接口 提現授權
     *
     * @return
     */
    @PostMapping("/updateUserInfoTx")
    public BatteryJSONResult updateUserInfoTx(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String nickName = obj.getString("nickName");
        String gender = obj.getString("gender");
        String language = obj.getString("language");
        String city = obj.getString("city");
        String province = obj.getString("province");
        String country = obj.getString("country");
        String avatarUrl = obj.getString("avatarUrl");

        String accountId = obj.getString("accountId");
        Integer accountType = obj.getInteger("accountType");


        AppUser updateAppUser = new AppUser();
        updateAppUser.setNickName(nickName);
        updateAppUser.setAvatar(avatarUrl);
        updateAppUser.setProvince(province);
        updateAppUser.setCity(city);
        updateAppUser.setId(appUser.getId());
        if ("0".equals(gender)) {
            updateAppUser.setSex(SexEnum.secret.type);
        } else if ("1".equals(gender)) {
            updateAppUser.setSex(SexEnum.man.type);
        } else {
            updateAppUser.setSex(SexEnum.woman.type);
        }
        appUserService.updateByPrimaryKeySelective(updateAppUser);


        if (accountType != null && StringUtils.isNotBlank(accountId)) {
            if (AccountTypeEnum.PARTNER.getCode().intValue() == accountType.intValue()) {
                // 合作商
                PartnerInstall partnerInstallUpdate = new PartnerInstall();
                partnerInstallUpdate.setPartnerId(accountId);
                partnerInstallUpdate.setAppOpenid(openid);
                partnerInstallService.updateByPrimaryKeySelective(partnerInstallUpdate);

            } else if (AccountTypeEnum.MERCHANT.getCode().intValue() == accountType.intValue()) {
                // 商戶
                MerchantInstall merchantInstallUpdate = new MerchantInstall();
                merchantInstallUpdate.setAppOpenid(openid);
                merchantInstallUpdate.setMerchantId(accountId);
                merchantInstallService.updateByPrimaryKeySelective(merchantInstallUpdate);
            }
        }

        AppUser responseAppuser = new AppUser();
        responseAppuser.setAvatar(appUser.getAvatar());
        responseAppuser.setNickName(appUser.getNickName());
        responseAppuser.setId(appUser.getId());
        responseAppuser.setAppUserCode(appUser.getAppUserCode());
        JSONObject requestJson = new JSONObject();
        requestJson.put("uid", appUser.getId());
        requestJson.put("user", responseAppuser);
        return BatteryJSONResult.ok(requestJson);
    }


    /**
     * 更新用户信息接口
     *
     * @return
     */
    @PostMapping("/updateUserInfo")
    public BatteryJSONResult updateUserInfo(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String nickName = obj.getString("nickName");
        String gender = obj.getString("gender");
        String language = obj.getString("language");
        String city = obj.getString("city");
        String province = obj.getString("province");
        String country = obj.getString("country");
        String avatarUrl = obj.getString("avatarUrl");

        AppUser updateAppUser = new AppUser();
        updateAppUser.setNickName(nickName);
        updateAppUser.setAvatar(avatarUrl);
        updateAppUser.setProvince(province);
        updateAppUser.setCity(city);
        updateAppUser.setId(appUser.getId());
        if ("0".equals(gender)) {
            updateAppUser.setSex(SexEnum.secret.type);
        } else if ("1".equals(gender)) {
            updateAppUser.setSex(SexEnum.man.type);
        } else {
            updateAppUser.setSex(SexEnum.woman.type);
        }
        appUserService.updateByPrimaryKeySelective(updateAppUser);

        AppUser responseAppuser = new AppUser();
        responseAppuser.setAvatar(appUser.getAvatar());
        responseAppuser.setNickName(appUser.getNickName());
        responseAppuser.setId(appUser.getId());
        responseAppuser.setAppUserCode(appUser.getAppUserCode());
        JSONObject requestJson = new JSONObject();
        requestJson.put("uid", appUser.getId());
        requestJson.put("user", responseAppuser);
        return BatteryJSONResult.ok(requestJson);
    }

    /**
     * 校验用户是否授权
     *
     * @return
     */
    @PostMapping("/checkAuth")
    public BatteryJSONResult checkAuth(HttpServletRequest request) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("openid信息不存在");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录");
        }
        JSONObject requestJson = new JSONObject();
        if (StringUtils.isNotBlank(appUser.getNickName())
                || StringUtils.isNotBlank(appUser.getAvatar())
                || StringUtils.isNotBlank(appUser.getCity())
                || StringUtils.isNotBlank(appUser.getProvince())) {
            requestJson.put("is_auth", 1);
        } else {
            requestJson.put("is_auth", 0);
        }
        return BatteryJSONResult.ok(requestJson);
    }

    /**
     * 获取用户信息
     *
     * @param request
     * @return
     */
    @PostMapping("/getInfo")
    public BatteryJSONResult getInfo(HttpServletRequest request) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("openid信息不存在");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录");
        }
        // TODO TODO
        // TODO -----------------> 押金计算 start
        // TODO TODO  这里展示用户未使用的押金
        BigDecimal deposit = BigDecimal.ZERO;
        List<Order> noUsedDeposits = orderService.noUsedWxDeposit(appUser.getId());
        if (noUsedDeposits != null && noUsedDeposits.size() > 0) {
            // TODO 查询该用户正常押金之和
            deposit = orderService.noUsedWxDepositSum(appUser.getId());
        }
        // TODO -----------------> 押金计算 end
        JSONObject requestJson = new JSONObject();
        requestJson.put("tel_", configService.selectConfigByKeyNoCache("sys.minapp.customerTel")); // 客服电话
        requestJson.put("deposit", deposit); // TODO 押金展示
        AppUser responseAppuser = new AppUser();
        responseAppuser.setAvatar(appUser.getAvatar());
        responseAppuser.setNickName(appUser.getNickName());
        responseAppuser.setId(appUser.getId());
        responseAppuser.setAppUserCode(appUser.getAppUserCode());
        responseAppuser.setBalance(appUser.getBalance()); // 用户钱包余额
        requestJson.put("user", responseAppuser);
        return BatteryJSONResult.ok(requestJson);
    }


    /**
     * 获取附近商家信息
     *
     * @param request
     * @param jsonObject
     * @return
     */
    @PostMapping("/getShopList")
    public BatteryJSONResult getShopList(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
        // TODO TODO

        BigDecimal longitude = jsonObject.getBigDecimal("longitude");
        BigDecimal latitude = jsonObject.getBigDecimal("latitude");
        Integer isList = jsonObject.getInteger("isList"); // 是否需要分页 （0 否 1 是）

        Map<String, Object> map = new HashMap<>();
        map.put("lng", longitude);
        map.put("lat", latitude);

        List<StoreVO> lists = null;
        if (isList == 1) {
            // 分页查询
            Integer pageSize = jsonObject.getInteger("page_size");
            Integer page = jsonObject.getInteger("page");
            Integer offset = pageSize * (page - 1);
            map.put("offset", offset);
            map.put("pageSize", pageSize);
        }
        // 获取设置的距离
        Integer distance = Integer.parseInt(configService.selectConfigByKeyNoCache("sys.store.distance"));
        map.put("distance", distance);
        lists = storeService.getShopList(map);
        List<StoreVO> storeVOS = null;
        if (isList == 0) {
            if (lists != null && lists.size() > 0) {
                storeVOS = new ArrayList<>();
                int size = lists.size();
                StoreVO storeVO = null;
                for (int i = 0; i < size; i++) {
                    storeVO = lists.get(i);
                    storeVO.setWidth(33);
                    storeVO.setHeight(37);
                    storeVOS.add(storeVO);
                }
            }
            JSONObject object = new JSONObject();
            object.put("list", storeVOS);
            return BatteryJSONResult.ok(object);
        }

        // 分页
        // 查询附近门店个数
        Integer total = storeService.selectStoreCountNear(map);
        if (total == 0) {
            JSONObject object = new JSONObject();
            object.put("list", storeVOS);
            object.put("total", total);
            return BatteryJSONResult.ok(object);
        }

        int size = lists.size();

        storeVOS = new ArrayList<>();
        StoreVO storeVO = null;
        for (int i = 0; i < size; i++) {
            storeVO = lists.get(i);
            storeVO.setWidth(33);
            storeVO.setHeight(37);

            // 一个门店可能有多个设备,直接根据门店ID获取对应设备的在库电池数
            BatteryNumber batteryNumber = deviceService.getWsDevInStockNumByStoreId(storeVO.getId());
            storeVO.setInStock(batteryNumber.getInStock()); // 在库电池
            storeVO.setNotInStock(batteryNumber.getAllBattery() - batteryNumber.getInStock()); // 空卡槽位置

            storeVOS.add(storeVO);
        }

        JSONObject object = new JSONObject();
        object.put("list", storeVOS);
        object.put("total", total);
        return BatteryJSONResult.ok(object);
    }


    /**
     * 获取店铺详情
     *
     * @param request
     * @param jsonObject
     * @return
     */
    @PostMapping("getShopInfo")
    public BatteryJSONResult getShopInfo(HttpServletRequest request, @RequestBody JSONObject jsonObject) {

        BigDecimal longitude = jsonObject.getBigDecimal("longitude");
        BigDecimal latitude = jsonObject.getBigDecimal("latitude");
        String storeId = jsonObject.getString("id");

        Store store = storeService.selectByPrimaryKey(storeId);

        StoreVO storeVO = new StoreVO();
        storeVO.setId(storeId);
        storeVO.setStoreName(store.getStoreName());
        storeVO.setDoorPhoto(store.getDoorPhoto());
        storeVO.setLocation(store.getLocation());
        storeVO.setDetailAddress(store.getDetailAddress());
        storeVO.setDistance((float) MapUtils.GetDistance(latitude.doubleValue(), longitude.doubleValue(), store.getLatitude().doubleValue(), store.getLongitude().doubleValue())); //

        BatteryNumber batteryNumber = deviceService.getWsDevInStockNumByStoreId(storeVO.getId());
        storeVO.setInStock(batteryNumber.getInStock()); // 在库电池
        storeVO.setNotInStock(batteryNumber.getAllBattery() - batteryNumber.getInStock()); // 空卡槽位置

        return BatteryJSONResult.ok(storeVO);

    }


    /**
     * 获取帮助信息
     *
     * @param request
     * @return
     */
    @PostMapping("/getHelps")
    public BatteryJSONResult getHelps(HttpServletRequest request) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        JSONArray arr = new JSONArray();
        // 查看使用帮助内容
        List<SysDictData> helps = configService.selectDictDataByType("sys_minapp_helps");
        if (helps != null && helps.size() > 0) {
            // 存在帮助信息
            int size = helps.size();
            SysDictData dictData = null;
            JSONObject object = null;
            for (int i = 0; i < size; i++) {
                dictData = helps.get(i);
                object = new JSONObject();
                object.put("helpTitle", dictData.getDictLabel());
                object.put("helpContent", dictData.getDictValue());
                arr.add(i, object);
            }
        }
        return BatteryJSONResult.ok(arr);
    }

    /**
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("/submitApply")
    public BatteryJSONResult submitApply(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String sn = obj.getString("sn");
        String true_name = obj.getString("true_name");
        String phone = obj.getString("phone");


        // 校验该用户是否提交过申请
        Member checkMember = memberService.checkMember(appUser.getId());
        if (checkMember != null) {
            return BatteryJSONResult.errorMsg("您已成为VIP!");
        }
        // 查询该用户是否已提交过申请
        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("未查询到对应的设备信息");
        }
        // 查询直营合作商
        Partner partner = partnerService.selectByPrimaryKey(device.getPartnerId());

        PartnerInstall install = partnerInstallService.selectByPrimaryKey(partner.getId());

        Member member = new Member();
        member.setId(sid.nextShort());
        member.setDevSn(sn);
        member.setAppUserId(appUser.getId());
        // 用户类型 微信小程序 1 支付宝小程序 2
        member.setUserType(1L);
        member.setTrueName(true_name);
        member.setPhone(phone);
        member.setProjectId(partner.getProjectId());
        member.setPartnerId(partner.getId());
        member.setMerchantId(device.getMerchantId());
        member.setStoreId(device.getStoreId());
        member.setCreateTime(DateUtils.getNowDate());
        member.setOrderFreeMinute(install.getOrderFreeMinute()); // VIP每单前X分钟免费
        member.setDailyOrderLimit(install.getDailyOrderLimit());
        member.setSuperiorId(partner.getParentId());
        memberService.insertSelective(member);

        AppUser appUserUpdate = new AppUser();
        appUserUpdate.setId(appUser.getId());
        appUserService.updateByPrimaryKeySelective(appUserUpdate);
        return BatteryJSONResult.ok();
    }


    /**
     * 校验设备类型，中转站
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("checkDeviceType")
    public BatteryJSONResult checkDeviceType(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        String sn = obj.getString("sn");
        if (StringUtils.isBlank(sn)) {
            return BatteryJSONResult.errorMsg("机柜SN不存在!");
        }
        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("该设备未激活!");
        }
        int isDisable = device.getIsDisable();
        if (YesOrNoEnum.YES.getCode() == isDisable) {
            return BatteryJSONResult.errorMsg("该设备已被禁止使用!");
        }
        int type = 0;
        JSONObject requestJson = new JSONObject();

        if (!device.getDevType().contains("DEV")) {
            // TODO 线设备 ---> DEV 为机柜设备 LINE 线设备
            type = 1;
        }
        requestJson.put("sn", sn);
        requestJson.put("type", type);
        return BatteryJSONResult.ok(requestJson);
    }


    /**
     * 扫码租借机柜设备(第一步骤)
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("deviceFirstStep")
    public BatteryJSONResult deviceFirstStep(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        String sn = obj.getString("sn");
        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("该设备未激活!");
        }

        boolean needAuthPhone = false;
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        // TODO TODO TODO 查询微信支付分是否存在欠款，如果存在则需要付押金租借

//        Used onLoanUsed = usedService.selectOnLoan(appUser.getId());
//        if (onLoanUsed != null) {
//            return BatteryJSONResult.errorMsg("存在正在借用中的订单！可在个人中心我的订单查看");
//        }
        // TODO TOOD 查询该用户正在租借中的订单个数
        int freeDeposit = 1; // 免押租借
        int inBorrowUsed = usedService.selectOnLoanCountByUid(appUser.getId());
        if (inBorrowUsed > 0) {
            // 存在正在租借中的订单
            int controlInBorrow = Integer.parseInt(configService.selectConfigByKeyNoCache("sys.borrow.control")); // 用户租借次数限制
            if (controlInBorrow == inBorrowUsed) {
                return BatteryJSONResult.errorMsg("您租借次数已达上限");
            }
            // 交押金限制
            int needToYz = Integer.parseInt(configService.selectConfigByKeyNoCache("sys.borrow.needToYz"));
            if (inBorrowUsed >= needToYz) {
                // 达到上限需要交押金
                freeDeposit = 0;
            }
        }

        // 判断用户是否已经授权手机号
        if (StringUtils.isBlank(appUser.getMobile())) {
            Integer authPhoneNeedCount = Integer.parseInt(configService.selectConfigByKeyNoCache("sys.appuser.warrantphone"));
            if (authPhoneNeedCount >= 0) {
                // 查询该用户租借次数
                Integer borrowCount = usedService.selectBorrowCount(appUser.getId());
                if (borrowCount >= authPhoneNeedCount) {
                    // 用于需要授权手机号
                    needAuthPhone = true;
                }
            }
        }

        Project project = projectService.selectByPrimaryKey(device.getProjectId());
        BigDecimal deposit = new BigDecimal(99);
        if (project != null) {
            deposit = project.getDeposit();
        }
        JSONObject requestJson = new JSONObject();

        if (needAuthPhone) {
            // 需要授权手机号
            requestJson.put("need_tel", 1);
            requestJson.put("need_tel_tip_1", configService.selectConfigByKeyNoCache("sys.authtel.but.tips")); // 页面上授权手机号按钮文字
            requestJson.put("need_tel_tip_2", configService.selectConfigByKeyNoCache("sys.authtel.but.tips2")); // 页面上授权手机号按钮底下文字描述
            requestJson.put("refuse_msg", configService.selectConfigByKeyNoCache("sys.authtel.refuse_msg")); // 用户拒绝授权手机号的提示
            requestJson.put("refuse_show", Integer.parseInt(configService.selectConfigByKeyNoCache("sys.authtel.refuse_show"))); // 拒绝是否需要提示文字 1 为需要 0 为不需要
            requestJson.put("refuse_after_borrow", Integer.parseInt(configService.selectConfigByKeyNoCache("sys.authtel.refuse_after_borrow"))); // 拒绝之后是否可以继续租借 1 可以继续租借 0 不允许继续租借
        } else {
            requestJson.put("need_tel", 0);
        }

        requestJson.put("sn", sn);
        requestJson.put("deposit", deposit);
        requestJson.put("fraction", 550); // 微信支付分要求
        requestJson.put("tips_1", "充电宝超期未归还，将自动代扣您" + project.getDeposit() + "元");
        requestJson.put("tips_2", configService.selectConfigByKeyNoCache("sys.wxMinApp.tipsOnLoan")); // 展示给用户看的提醒


        // 门店一系列配置信息
        String mealMsg = "";
        String freeMsg = "";
        BigDecimal price = BigDecimal.ZERO;
        StoreInstall storeInstall = storeInstallService.selectByPrimaryKey(device.getStoreId());
        if (storeInstall == null) {
//            return BatteryJSONResult.errorMsg("该设备未部署");
            // TODO 如果该设备未部署,无默认套餐，那我默认的价格套餐 为 2分钟免费 2元一小时，日封顶20元，总封99元
            price = new BigDecimal(2);
            freeMsg = "前2分钟免费";
            requestJson.put("unit", "元/小时");
            mealMsg = mealMsg + freeMsg + "," + price + "元/小时,每日封顶20元,总封顶" + deposit + "元";
            requestJson.put("freeMsg", "前2分钟内免费使用"); //

            requestJson.put("storeName", "仓库"); //
            requestJson.put("storeAddress", "仓库"); //
            requestJson.put("mealMsg_01", "每24小时封顶20元,最高封顶" + deposit + "元");
            requestJson.put("mealMsg_02", "租借时长不足1小时,按1小时计费");
        } else {
            String mealMsg_01 = "每24小时封顶" + storeInstall.getDayMax() + "元,最高封顶" + deposit + "元";
            String mealMsg_02 = "";
            price = storeInstall.getPrice();
            if (storeInstall.getFreeM() > 0) {
                freeMsg = "前" + storeInstall.getFreeM() + "分钟免费,";
            }
            if (DevMealTimeEnum.HALF_HOUR.type.intValue() == storeInstall.getUnitTime().intValue()) {
                requestJson.put("unit", "元/半小时");
                mealMsg = mealMsg + freeMsg + storeInstall.getPrice() + "元/半小时,每日封顶" + storeInstall.getDayMax() + "元,总封顶" + deposit + "元";
                mealMsg_02 = "租借时长不足30分钟,按30分钟计费";
            } else if (DevMealTimeEnum.FIFTEEN_MINUTES.type.intValue() == storeInstall.getUnitTime().intValue()) {
                requestJson.put("unit", "元/15分钟");
                mealMsg = mealMsg + freeMsg + storeInstall.getPrice() + "元/15分钟,每日封顶" + storeInstall.getDayMax() + "元,总封顶" + deposit + "元";
                mealMsg_02 = "租借时长不足15分钟,按15分钟计费";
            } else {
                requestJson.put("unit", "元/小时");
                mealMsg = mealMsg + freeMsg + storeInstall.getPrice() + "元/小时,每日封顶" + storeInstall.getDayMax() + "元,总封顶" + deposit + "元";
                mealMsg_02 = "租借时长不足1小时,按1小时计费";
            }
            if (storeInstall.getFreeM() > 0) {
                requestJson.put("freeMsg", "前" + storeInstall.getFreeM() + "分钟内免费使用"); //
            }
            Store store = storeService.selectByPrimaryKey(storeInstall.getStoreId());
            requestJson.put("storeName", store.getStoreName()); //
            requestJson.put("storeAddress", store.getDetailAddress()); //
            requestJson.put("mealMsg_01", mealMsg_01);
            requestJson.put("mealMsg_02", mealMsg_02);
        }
        Advert advert = advertService.selectByUseSceneType(1); // 充电宝租借界面
        if (advert != null && advert.getIsClose() == YesOrNoEnum.NO.getCode().intValue()) {
            requestJson.put("isShow", 1);
            requestJson.put("adImg", advert.getImg());
        } else {
            requestJson.put("isShow", 0);
            requestJson.put("adImg", "");
        }
        requestJson.put("price", price);
        requestJson.put("freeDeposit", freeDeposit); // TODO 默认全部免押租借
        requestJson.put("mealMsg", mealMsg);
        return BatteryJSONResult.ok(requestJson);
    }

    /**
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("deviceBorrow")
    public BatteryJSONResult deviceBorrow(HttpServletRequest request, @RequestBody JSONObject obj) {

        // WS设备在租借前，需要判定设备
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        // 判断该用户是否被冻结使用
        if (appUser.getIsFrozen() == 1) {
            // 该用户被冻结使用
            return BatteryJSONResult.errorMsg("您的账号被冻结。冻结原因:[" + appUser.getReason() + "]!");
        }

        String sn = obj.getString("sn");
        Integer freeDeposit = obj.getInteger("freeDeposit");
        String used_id = obj.getString("used_id");


        // 查询是否存在借用中的订单
//        Used onLoanUsed = usedService.selectOnLoan(appUser.getId());
//        if (onLoanUsed != null) {
//            return BatteryJSONResult.errorMsg("存在正在借用中的订单！可在个人中心我的订单查看");
//        }

        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("该设备未激活！");
        }

        if (!device.getDevType().contains("DEV")) {
            // 不是机柜设备
            return BatteryJSONResult.errorMsg("请扫机柜上二维码！");
        }


        String devType = device.getDevType();
        if (DevTypeEnum.WS_DEV_4.getCode().equals(devType)
                || DevTypeEnum.WS_DEV_6.getCode().equals(devType)
                || DevTypeEnum.WS_DEV_9.getCode().equals(devType)
                || DevTypeEnum.WS_DEV_12.getCode().equals(devType)) {
            BatteryJSONResult boxStatusResult = WsDevUtils.boxStatus(sn);
            if (boxStatusResult.getCode() == 0) {
                // 设备不在线
                return boxStatusResult;
            }
        } else {
            return BatteryJSONResult.errorMsg("不存在该类型的设备");
        }

        StoreInstall storeInstall = storeInstallService.selectByPrimaryKey(device.getStoreId());
//        if (storeInstall == null) {
//            return BatteryJSONResult.errorMsg("该设备未有商家激活");
//        }

        if (freeDeposit == 0) {
            // 微信交押金租借
            // TODO ======================= 开始计算押金 start =========================
            List<Order> noUsedDeposits = orderService.noUsedWxDepositNoSign(appUser.getId()); // 查询未使用的微信押金
            Project project = projectService.selectByPrimaryKey(device.getProjectId());
            BigDecimal deposit = new BigDecimal(99);
            if (project != null) {
                deposit = project.getDeposit();
            }
            if (noUsedDeposits == null) {
                // 该用户未支付押金，第一次租借
                JSONObject requestJsonObj = new JSONObject();
                requestJsonObj.put("amount", deposit);
                requestJsonObj.put("sn", sn);
                return BatteryJSONResult.build(3, "请充值押金", requestJsonObj);
            } else {
                BigDecimal balance = appUser.getBalance();
                if (balance.compareTo(BigDecimal.ZERO) < 0) {
                    // 用户产生了租借费用，需要先支付该笔金额
                    BigDecimal absBalance = balance.abs(); // 用户欠费金额
                    // 获取押金租借的未支付订单
                    Used noPayUsed = usedService.selectOneNoPay(appUser.getId(), UserTypeEnum.WX.getCode(), BorrowModeEnum.DEPOSIT.type);
                    if (noPayUsed != null) {
                        // 存在未支付的押金订单
                        BigDecimal money = noPayUsed.getAmountPaid();
                        if (absBalance.subtract(money).compareTo(BigDecimal.ZERO) == 0) {
                            // 钱包余额与租借记录的订单金额一致，用户需要支付
                            JSONObject requestJson = new JSONObject();
                            requestJson.put("amount", absBalance); //  用户欠费金额
                            requestJson.put("sn", sn);
                            requestJson.put("used_id", noPayUsed.getId());
                            return BatteryJSONResult.build(4, "您存在" + absBalance + "元未支付的订单", requestJson);
                        } else {
                            return BatteryJSONResult.errorMsg("租借失败，待付款金额与钱包余额里面金额不一致，请联系管理员");
                        }
                    }
                    return BatteryJSONResult.errorMsg("租借失败，发生错误，未查询到对应的未付款订单");
                } else {
                    // TODO TODO 一笔押金一笔订单
                    if (noUsedDeposits.size() > 0) {
                        Order noUsedDeposit = noUsedDeposits.get(0);
                        // 存在未使用的押金
                        // 该用户未产生租借费用，钱包余额为0,且存在押金， 那么可以直接开始租借
                        // 两种租借方式，配合进行
                        BatteryJSONResult result = null;
                        String borrowWay = configService.selectConfigByKeyNoCache("sys.wsDev.borrowWay");
                        if ("2".equals(borrowWay)) {
                            // 传统方式租借+强弹租借(必须保证库存是最新的)
                            result = usedService.wsDevTips2DepositBorrowBattery(noUsedDeposit, appUser, storeInstall, device);
                        } else {
                            // 传统方式租借
                            result = usedService.wsDevTips1DepositBorrowBattery(noUsedDeposit, appUser, storeInstall, device);
                        }
                        return result;
                    } else {
                        // 该用户未支付押金，第一次租借
                        JSONObject requestJsonObj = new JSONObject();
                        requestJsonObj.put("amount", deposit);
                        requestJsonObj.put("sn", sn);
                        return BatteryJSONResult.build(3, "请充值押金", requestJsonObj);
                    }
                }
            }
        } else {
            // 免押租借
            if (StringUtils.isBlank(used_id)) {
                // 微信未授权租借
                Project project = projectService.selectByPrimaryKey(device.getProjectId());
                BigDecimal deposit = new BigDecimal(99);
                if (project != null) {
                    deposit = project.getDeposit();
                }
                JSONObject requestJSON = new JSONObject();
                requestJSON.put("amount", deposit);
                requestJSON.put("sn", sn);
                return BatteryJSONResult.build(3, "创建微信免押订单", requestJSON);
            } else {
                String key = RedisKeyHelper.getWxBorrowKey(openid);
                boolean lock = RedisCommonLock.commonLock(key);
                if (!lock) {
                    return BatteryJSONResult.errorMsg("系统繁忙，请稍后在试");
                }
                try {
                    // 查询对应的授权租借订单
                    AuthUsed authUsed = authUsedService.selectByPrimaryKey(used_id);
                    if (authUsed == null) {
                        return BatteryJSONResult.errorMsg("未查询到对应的授权租借记录");
                    }
                    // 通过微信支付分接口查询
                    BatteryJSONResult result = authUsedService.queryrentbill(authUsed, true);
                    if (result.getCode() == 0) {
                        return result;
                    }
                    BatteryJSONResult result_ = null;
                    String borrowWay = configService.selectConfigByKeyNoCache("sys.wsDev.borrowWay");
                    if ("2".equals(borrowWay)) {
                        // 传统方式租借+强弹租借(必须保证库存是最新的)
                        result_ = usedService.wsDevTips2FreeDepositBorrowBattery(authUsed, appUser, storeInstall, device);
                    } else {
                        result_ = usedService.wsDevTips1FreeDepositBorrowBattery(authUsed, appUser, storeInstall, device);
                    }
                    if (result_.getCode() == 1) { //
                        // 租借成功
                        return result_;
                    }
                    // 租借失败，则撤销该笔授权订单
                    BatteryJSONResult cxWxFreeResult = authUsedService.doWxRevokeOrder(authUsed.getUsedId());
                    if (cxWxFreeResult.getCode() == 1) {
                        return BatteryJSONResult.build(4, "租借失败，对应的支付分订单已撤销！可重新发起租借", null);
                    }
                    return cxWxFreeResult;
                } catch (Exception e) {
                    e.printStackTrace();
                    return BatteryJSONResult.errorMsg("系统繁忙，请稍后再试");
                } finally {
                    RedisCommonLock.unlock(key);
                }
            }
        }
    }

    /**
     * 创建微信支付分订单
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("doWxfree")
    public BatteryJSONResult doWxfree(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }

        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        BigDecimal amount = obj.getBigDecimal("amount");
        String sn = obj.getString("sn");

        if (amount == null) {
            return BatteryJSONResult.errorMsg("请输入正确的金额!");
        }

        if (amount.subtract(new BigDecimal(0.01)).compareTo(BigDecimal.ZERO) < 0) {
            return BatteryJSONResult.errorMsg("金额不能小于0.01");
        }

        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("该设备未激活!");
        }

        StoreInstall storeInstall = storeInstallService.selectByPrimaryKey(device.getStoreId());
//        if (storeInstall == null) {
//            return BatteryJSONResult.errorMsg("该设备未部署");
//        }
        return authUsedService.createrentbill(appUser, device, storeInstall, amount);
    }


    /**
     * 查询用户是否确认租借
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("queryWxfreeStatus")
    public BatteryJSONResult queryWxfreeStatus(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        String query_id = obj.getString("query_id");
        if (StringUtils.isBlank(query_id)) {
            return BatteryJSONResult.errorMsg("单据为空!");
        }

        // 查询设备
        JSONObject reqQuery = new JSONObject();
        reqQuery.put("service_id", Constants.wxServiceId);
        reqQuery.put("query_id", query_id);
        reqQuery.put("appid", Constants.wxMinAppID);
        BatteryJSONResult result = null;
        try {
            result = PayscoreUtils.queryrentbill(reqQuery, false, Constants.wx_cret_keyPath_apiclient_key, Constants.wxMerchantId, Constants.certSerialNo);
        } catch (Exception e) {
            e.printStackTrace();
            return BatteryJSONResult.errorMsg("发生错误，请联系客服");
        }
        if (result == null) {
            return BatteryJSONResult.errorMsg("发生错误，请联系客服");
        }
        if (result.getCode() == 0) {
            return result;
        }
        String body = (String) result.getData();
        JSONObject jsonObj = JSONObject.parseObject(body);
        String state = jsonObj.getString("state"); // 服务订单状态
        String state_description = jsonObj.getString("state_description"); // 订单状态说明
        String out_order_no = jsonObj.getString("out_order_no"); // 商户服务订单号

        AuthUsed authUsed = authUsedService.selectByOutOrderNo(out_order_no);
        if (UsedAuthStateEnum.DOING.type.equals(state)
                && authUsed != null
                && UsedAuthStateDescriptionEnum.USER_CONFIRM.type.equals(state_description)) {
            JSONObject requestJsonObj = new JSONObject();
            UsedBasics basics = usedBasicsService.selectByPrimaryKey(authUsed.getUsedId());
            requestJsonObj.put("sn", basics.getRentDeviceSn());
            requestJsonObj.put("used_id", authUsed.getUsedId());
            return BatteryJSONResult.ok(requestJsonObj);
        } else {
            return BatteryJSONResult.errorMsg("未查询到对应的微信支付分授权订单");
        }
    }


    /**
     * 查询电池是否租借成功
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("checkUsed")
    public BatteryJSONResult checkUsed(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        String used_id = obj.getString("used_id");

        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("查询电池是否租借成功-未查找到对应的租借订单");
        }
        if (LeaseStateEnum.SUCCESS.getCode() == used.getLeaseState()) {
            // 租借成功
            JSONObject requestJSONObj = new JSONObject();
            requestJSONObj.put("status", 1);
            requestJSONObj.put("used_id", used_id);
            return BatteryJSONResult.ok(requestJSONObj);
        } else {
            JSONObject requestJSONObj = new JSONObject();
            requestJSONObj.put("status", 0);
            requestJSONObj.put("used_id", used_id);
            return BatteryJSONResult.ok(requestJSONObj);
        }
    }


    /**
     * 查询使用记录-（使用于租借成功或者失败页面）
     *
     * @param request
     * @return
     */
    @PostMapping("getUsed")
    public BatteryJSONResult getUsed(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录");
        }
        String used_id = obj.getString("used_id");

        UsedBasics usedBasics = usedBasicsService.selectByPrimaryKey(used_id);
        Used used = usedService.selectByPrimaryKey(used_id);

        JSONObject requestJSON = new JSONObject();
        Device device = deviceService.selectByPrimaryKey(usedBasics.getRentDeviceId());
        int dev = 0;
        String img = "";
        int slot = usedBasics.getRentSlotNo(); // 租借卡槽位
        if (device != null) {
            String devType = device.getDevType();
            if (DevTypeEnum.WS_DEV_4.getCode().equals(devType)) {
                dev = 4;
                img = "https://www.zjsuichong.com/min/images/40" + slot + ".png";
            } else if (DevTypeEnum.WS_DEV_6.getCode().equals(devType)) {
                dev = 6;
                img = "https://www.zjsuichong.com/min/images/60" + slot + ".png";
            } else if (DevTypeEnum.WS_DEV_12.getCode().equals(devType)) {
                dev = 12;
                if (slot >= 10) {
                    img = "https://www.zjsuichong.com/min/images/12" + slot + ".png";
                } else {
                    img = "https://www.zjsuichong.com/min/images/120" + slot + ".png";
                }
            } else if (DevTypeEnum.WS_DEV_9.getCode().equals(devType)) {
                dev = 9;
                img = "https://www.zjsuichong.com/min/images/90" + slot + ".png";
            }
        }

        // 同时判断该用户是否是免费用户
        int isVip = 0; // 是否优惠
        int freeCx = 0;
        int freeTime = 0;
        if (appUser.getIsFree() == YesOrNoEnum.YES.getCode().intValue()) {
            // 是免费用户
            Member member = memberService.selectTrueMember(appUser.getId());
            if (member != null) {
                if (YesOrNoEnum.NO.getCode().intValue() == member.getIsSuper().intValue()) {
                    if (member.getStoreId().equals(used.getStoreId())) {
                        // 该用户是该门店下的VIP
                        isVip = 1;
                    }
                } else {
                    isVip = 1;
                }
                if (isVip == 1) {
                    int dailyOrderLimit = member.getDailyOrderLimit(); // 每天免费订单数
                    if (dailyOrderLimit > 0) {
                        int todayFreeCount = usedService.selectCountByTodayFree(appUser.getId());
                        freeCx = dailyOrderLimit - todayFreeCount;
                        if (freeCx > 0) {
                            isVip = 1;
                            freeTime = member.getOrderFreeMinute();
                        }
                    }
                }
            }
        }
        requestJSON.put("freeTime", freeTime);
        requestJSON.put("isVip", isVip);
        requestJSON.put("freeCx", freeCx);
        requestJSON.put("dev", dev);
        requestJSON.put("slot", slot);
        requestJSON.put("img", img);
        requestJSON.put("tel", configService.selectConfigByKeyNoCache("sys.minapp.customerTel")); // 客服电话
        requestJSON.put("lendTime", usedBasics.getRentDate()); // 借出时间
        requestJSON.put("mealName", used.getMealContent());
        requestJSON.put("used_id", used_id);
        requestJSON.put("usedSn", used.getOrderNumber()); // 订单号
        requestJSON.put("sceneName", used.getStoreName());
        requestJSON.put("batterySn", usedBasics.getBatterySn());
        return BatteryJSONResult.ok(requestJSON);
    }


    /**
     * 租借失败，更新租借失败状态，同时撤销微信支付分订单
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("doRevokeOrder")
    public BatteryJSONResult doRevokeOrder(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String used_id = obj.getString("used_id");

        // 更新租借状态为失败，如果是授权订单，则撤销
        return authUsedService.doWxRevokeOrder(used_id);
    }


    /**
     * 统一下单
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("wxPayRecharge")
    public BatteryJSONResult wxPayRecharge(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        BigDecimal amount = obj.getBigDecimal("amount");
        String sn = obj.getString("sn"); // 必传项, TODO 如果为充值，则为 RECHARGE 后续在考虑充值
        Integer type = obj.getInteger("type"); // 1 押金  2 机柜租赁费用 3 线租借费用 // 订单类型: 押金 机柜租赁费用 线租借费用
        String extra = obj.getString("extra"); // 额外参数 // 如果是机柜租赁费用，则该额外参数为 used_id

        // 支付押金 以及线租借必然会携带机柜SN信息
        if (StringUtils.isBlank(sn)) {
            return BatteryJSONResult.errorMsg("必填项SN为空");
        }

        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("未查询到对应的设备信息！");
        }
        // 微信统一下单

        String key = RedisKeyHelper.getWxPayRechargeKey(openid);
        boolean lock = RedisCommonLock.commonLock(key);
        if (!lock) {
            return BatteryJSONResult.errorMsg("系统繁忙，请稍后在试");
        }
        try {
            return orderService.wxPayRecharge(appUser, device, amount, type, extra);
        } catch (Exception e) {
            e.printStackTrace();
            return BatteryJSONResult.errorMsg("系统繁忙，请稍后再试");
        } finally {
            RedisCommonLock.unlock(key);
        }
    }


    /**
     * 校验订单是否成功
     *
     * @return
     */
    @PostMapping("checkOrderStatus")
    public BatteryJSONResult checkOrderStatus(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        String order_id = obj.getString("order_id");
        Order order = orderService.selectByPrimaryKey(order_id);
        if (order == null) {
            return BatteryJSONResult.errorMsg("未查询到对应的订单");
        }

        if (OrderTradeStateEnum.PAY_SUCCESS.getCode() == order.getTradeState().intValue()) {
            // 支付成功
            JSONObject requestJsonObj = new JSONObject();
            requestJsonObj.put("status", 1);
            requestJsonObj.put("order_id", order_id);
            requestJsonObj.put("sn", order.getSn());
            return BatteryJSONResult.ok(requestJsonObj);
        }

        String out_trade_no = order.getOutOrderNo();
        WxPayOrderQueryResult result = null;
        try {
            result = wxService.queryOrder(null, out_trade_no);
        } catch (WxPayException e) {
            e.printStackTrace();
            return BatteryJSONResult.errorMsg("查询订单是否支付成功接口请求失败");
        }
        if (result == null) {
            return BatteryJSONResult.errorMsg("查询订单是否支付成功接口请求失败");
        }
        String return_code = result.getReturnCode();
        String result_code = result.getResultCode();
        String trade_state = result.getTradeState();
        String transaction_id = result.getTransactionId();
        if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code) && "SUCCESS".equals(trade_state)) {

            Order orderUpdate = new Order();
            orderUpdate.setId(order.getId());
            orderUpdate.setTransactionId(transaction_id);
            orderUpdate.setTradeState(OrderTradeStateEnum.PAY_SUCCESS.getCode());
            orderService.updateOrder(order);
            // 支付成功
            JSONObject requestJsonObj = new JSONObject();
            requestJsonObj.put("status", 1);
            requestJsonObj.put("order_id", order_id);
            requestJsonObj.put("sn", order.getSn());
            return BatteryJSONResult.ok(requestJsonObj);
        }

        JSONObject requestJsonObj = new JSONObject();
        requestJsonObj.put("status", 0);
        requestJsonObj.put("order_id", order_id);
        return BatteryJSONResult.ok(requestJsonObj);
    }


    /**
     * 退押
     *
     * @param request
     * @return
     */
    @PostMapping("returnDeposit")
    public BatteryJSONResult returnDeposit(HttpServletRequest request) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        List<Used> onLoanUsed = usedService.selectOnLoan(appUser.getId());
        if (onLoanUsed != null && onLoanUsed.size() > 0) {
            return BatteryJSONResult.errorMsg("存在正在借用中的订单！可在个人中心我的订单查看");
        }

        // TODO  暂时不能在这里退押 , 为了保证不会错乱
        return BatteryJSONResult.errorMsg("存在正在借用中的订单！可在个人中心我的订单查看");

        // 查询该用户是否存在押金
//        List<Order> noUsedDeposits = orderService.noUsedWxDeposit(appUser.getId());
//        if (noUsedDeposits == null) {
//            return BatteryJSONResult.errorMsg("您的押金不存在，如有疑问请联系客服！");
//        }
//
//        // TODO 退押金一个一个退
//        Order noUsedDeposit = noUsedDeposits.get(0);
//
//        String key = RedisKeyHelper.getWxRefundDepositKey(openid);
//        boolean lock = RedisCommonLock.commonLock(key);
//        if (!lock) {
//            return BatteryJSONResult.errorMsg("系统繁忙，请稍后在试");
//        }
//        try {
//            BigDecimal balance = appUser.getBalance();
//            BigDecimal refund_fee = null; // 退款金额
//            if (balance.compareTo(BigDecimal.ZERO) < 0) {
//                BigDecimal absBalance = balance.abs();
//                // 存在欠款金额
//                refund_fee = noUsedDeposit.getTotalFee().subtract(absBalance);
//            } else {
//                refund_fee = noUsedDeposit.getTotalFee();
//            }
//            if (refund_fee.compareTo(BigDecimal.ZERO) <= 0) {
//                return BatteryJSONResult.errorMsg("您的押金已使用完毕,如有疑问,请拨打客服电话");
//            }
//            // TODO TODO
//            return refundOrderService.wxRefundDeposit(appUser, noUsedDeposit, refund_fee);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return BatteryJSONResult.errorMsg("系统繁忙，请稍后再试");
//        } finally {
//            RedisCommonLock.unlock(key);
//        }
    }


    /**
     * 获取用户使用记录 (仅显示最近1个月订单)
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("usedList")
    public BatteryJSONResult usedList(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        Integer pageSize = obj.getInteger("page_size");
        Integer page = obj.getInteger("page");
        Integer offset = pageSize * (page - 1);

        Date lastMonth = DateUtils.getDateLastMonth(new Date());
        Map<String, Object> map = new HashMap<>();
        map.put("appUserId", appUser.getId());
        map.put("offset", offset);
        map.put("pageSize", pageSize);
        map.put("limitDate", lastMonth);
        List<UsedVO> lists = usedService.selectListByMap(map);


        Integer total = usedService.selectListByMapCout(map);
//        Integer total = usedService.selectCountLastMonth(appUser.getId(), lastMonth);
//        Integer noAuthNum = authUsedService.selectCountNoAuth(appUser.getId(), lastMonth);
//        total = total - noAuthNum;
        List<UsedVO> thisLists = null;
//        AuthUsed authUsed = null;
        boolean flag = false;
        if (lists != null && lists.size() > 0) {
            thisLists = new ArrayList<>();
            Date date = DateUtils.getNowDate();
            int size = lists.size();
            UsedVO usedVO = null;
            for (int i = 0; i < size; i++) {
                usedVO = lists.get(i);

                // 查询微信支付分订单是否未确认租借
//                authUsed = authUsedService.selectByPrimaryKey(usedVO.getId());
//                if (authUsed != null) {
//                    if (authUsed.getState() == null || UsedAuthStateEnum.CREATED.type.equals(authUsed.getState()) || usedVO.getRentDate() == null) {
//                        // 商户创建微信支付分订单，但是用户未确认租借。
//                        // 该类型订单不展示
//                        flag = true;
//                    }
//                }
//                if (flag) {
//                    flag = false;
////                    total = total - 1;
//                    continue;
//                } else
                {
                    usedVO.setUsedTypeMsg("机柜订单");
                    if (DevTypeEnum.WS_DEV_4.getCode().equals(usedVO.getDevType())) {
                        usedVO.setDevTypeMsg(DevTypeEnum.WS_DEV_4.getValue());
                    } else if (DevTypeEnum.WS_DEV_6.getCode().equals(usedVO.getDevType())) {
                        usedVO.setDevTypeMsg(DevTypeEnum.WS_DEV_6.getValue());
                    } else if (DevTypeEnum.WS_DEV_12.getCode().equals(usedVO.getDevType())) {
                        usedVO.setDevTypeMsg(DevTypeEnum.WS_DEV_12.getValue());
                    } else if (DevTypeEnum.WS_DEV_9.getCode().equals(usedVO.getDevType())) {
                        usedVO.setDevTypeMsg(DevTypeEnum.WS_DEV_9.getValue());
                    } else if (DevTypeEnum.R_LINE.getCode().equals(usedVO.getDevType())) {
                        usedVO.setDevTypeMsg(DevTypeEnum.R_LINE.getValue());
                        usedVO.setUsedTypeMsg("线订单");
                    } else {
                        usedVO.setUsedTypeMsg("其他设备");
                    }
                    if (usedVO.getLeaseState() == 1) {
                        // 租借成功
                        if (usedVO.getIsBack() == 1) {
                            date = usedVO.getBackDate();
                        }
                        usedVO.setUseTime(DateUtils.getDatePoor(date, usedVO.getRentDate()));
                    }
                    thisLists.add(usedVO);
                }
            }
        }
        JSONObject object = new JSONObject();
        object.put("total", total);
        object.put("list", thisLists);
        return BatteryJSONResult.ok(object);
    }


    /**
     * 根据使用id获取对应的租借详情信息
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("getUsedInfo")
    public BatteryJSONResult getUsedInfo(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String used_id = obj.getString("used_id");
        UsedVO usedVO = usedService.getUsedInfoById(used_id);
        return BatteryJSONResult.ok(usedVO);
    }


    /**
     * 订单未支付-->发起支付
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("doToPay")
    public BatteryJSONResult doToPay(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        String used_id = obj.getString("used_id");
        String order_id = obj.getString("order_id");

        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("未查询到对应的租借订单");
        }
        BigDecimal money = used.getAmountPaid();
        if (money.compareTo(BigDecimal.ZERO) == 0) {
            return BatteryJSONResult.errorMsg("金额为0，无需支付");
        }
        if (StringUtils.isBlank(order_id)) {
            UsedBasics basics = usedBasicsService.selectByPrimaryKey(used_id);
            JSONObject requestJSON = new JSONObject();
            requestJSON.put("amount", money);
            requestJSON.put("sn", basics.getRentDeviceSn());
            requestJSON.put("type", 2); // 机柜租赁费用
            requestJSON.put("used_id", used.getId());
            return BatteryJSONResult.build(2, "需发起支付", requestJSON);
        }

        Order order = orderService.selectOrderById(order_id);
        String out_trade_no = order.getOutOrderNo();
        WxPayOrderQueryResult result = null;
        try {
            result = wxService.queryOrder(null, out_trade_no);
        } catch (Exception e) {
            e.printStackTrace();
            return BatteryJSONResult.errorMsg("查询订单是否支付成功接口请求失败");
        }
        if (result == null) {
            return BatteryJSONResult.errorMsg("查询订单是否支付成功接口请求失败");
        }
        String return_code = result.getReturnCode();
        String result_code = result.getResultCode();
        String trade_state = result.getTradeState();
        if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code) && "SUCCESS".equals(trade_state)) {
            // 支付成功
            JSONObject requestJSON = new JSONObject();
            requestJSON.put("status", 1);
            requestJSON.put("order_id", order.getId());
            requestJSON.put("used_id", used_id);
            return BatteryJSONResult.build(1, "订单支付成功!", requestJSON);
        }
        return BatteryJSONResult.errorMsg("订单未支付");
    }


    /**
     * 充电线租借
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("lineScan")
    public BatteryJSONResult lineScan(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String sn = obj.getString("sn");
        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("该设备未激活！");
        }

        String devType = device.getDevType();
        if (!DevTypeEnum.R_LINE.getCode().equals(devType)) {
            return BatteryJSONResult.errorMsg("请扫正确的二维码！");
        }

        // 判断用户是否存在正在租借中的充电线订单
        UsedLineVO lineInRun = usedBasicsService.selectLineInRun(appUser.getId(), DateUtils.getNowDate(), sn);
        if (lineInRun != null) {
            JSONObject requestJSON = new JSONObject();
            requestJSON.put("sn", sn);
            requestJSON.put("used_id", lineInRun.getUsedId());
            requestJSON.put("password", lineInRun.getPassword());
            return BatteryJSONResult.build(2, "充电线已有订单", requestJSON);
        }

        // 该vip是否出现支付完毕，而不出密码的情况,针对当前
        Order order = orderService.isHasOrderNotLineOrder(appUser.getId(), sn);
        if (order != null) {
            // 存在
            JSONObject responseOBJ = usedService.lineBorrow(order, appUser, device);
            return BatteryJSONResult.build(2, "充电线已有订单", responseOBJ);
        }

        // 查询对应的商家信息
        StoreInstall storeInstall = storeInstallService.selectByPrimaryKey(device.getStoreId());
//        if (storeInstall == null) {
//            return BatteryJSONResult.errorMsg("该设备线未部署！");
//        }
        JSONObject responseObj = new JSONObject();
        JSONArray array = new JSONArray();
        if (storeInstall != null) {
            if (StringUtils.isBlank(storeInstall.getChargerPrice())) {
                return BatteryJSONResult.errorMsg("门店未选择对应的线套餐");
            }
            JSONArray arr = JSON.parseArray(storeInstall.getChargerPrice());
            JSONObject zeroObj = new JSONObject();
            int xb = 0;
            for (int i = 0; i < arr.size(); i++) {
                boolean flag = false;
                JSONObject object = arr.getJSONObject(i);
                JSONObject mealObj = new JSONObject();
                String minute = object.getString("min");
                BigDecimal money = object.getBigDecimal("money");
                if (RLineMealTimeEnum.ONE_HOUR.type.equals(minute)) {
                    mealObj.put("value", "1小时" + money + "元");
                    mealObj.put("amount", money);
                    mealObj.put("time", minute);
                    flag = true;
                } else if (RLineMealTimeEnum.THREE_HOUR.type.equals(minute)) {
                    mealObj.put("value", "3小时" + money + "元");
                    mealObj.put("amount", money);
                    mealObj.put("time", minute);
                    flag = true;
                } else if (RLineMealTimeEnum.FIVE_HOUR.type.equals(minute)) {
                    mealObj.put("value", "5小时" + money + "元");
                    mealObj.put("amount", money);
                    mealObj.put("time", minute);
                    flag = true;
                } else if (RLineMealTimeEnum.TWELVE_HOUR.type.equals(minute)) {
                    mealObj.put("value", "12小时" + money + "元");
                    mealObj.put("amount", money);
                    mealObj.put("time", minute);
                    flag = true;
                }
                if (flag) {
                    if (xb == 0) {
                        mealObj.put("checked", true);
                        zeroObj = mealObj;
                    }
                    array.add(xb, mealObj);
                    xb++;
                }
            }
            responseObj.put("is_show", 1);
            Store store = storeService.selectByPrimaryKey(storeInstall.getStoreId());
            responseObj.put("storeName", store.getStoreName());
            responseObj.put("priceMeal", array);
            responseObj.put("leaseTime", zeroObj.getString("time"));
            responseObj.put("leaseMoney", zeroObj.getString("amount"));
        } else {
            JSONObject mealObj_1 = new JSONObject();
            mealObj_1.put("value", "1小时2元");
            mealObj_1.put("amount", 2);
            mealObj_1.put("time", RLineMealTimeEnum.ONE_HOUR.type);
            mealObj_1.put("checked", true);
            array.add(0, mealObj_1);

            JSONObject mealObj_2 = new JSONObject();
            mealObj_2.put("value", "3小时6元");
            mealObj_2.put("amount", 6);
            mealObj_2.put("time", RLineMealTimeEnum.THREE_HOUR.type);
            array.add(1, mealObj_2);

            JSONObject mealObj_3 = new JSONObject();
            mealObj_3.put("value", "5小时10元");
            mealObj_3.put("amount", 10);
            mealObj_3.put("time", RLineMealTimeEnum.FIVE_HOUR.type);
            array.add(2, mealObj_3);

            JSONObject mealObj_4 = new JSONObject();
            mealObj_4.put("value", "12小时20元");
            mealObj_4.put("amount", 20);
            mealObj_4.put("time", RLineMealTimeEnum.TWELVE_HOUR.type);
            array.add(3, mealObj_4);

            responseObj.put("priceMeal", array);
            responseObj.put("is_show", 0);
            responseObj.put("storeName", "");
            responseObj.put("leaseTime", mealObj_1.getString("time"));
            responseObj.put("leaseMoney", mealObj_1.getString("amount"));
        }
        // is vip or no
        boolean flag = false;
        Member member = memberService.selectTrueMember(appUser.getId());
        if (member != null) {
            if (YesOrNoEnum.NO.getCode().intValue() == member.getIsSuper().intValue()) {
                // 普通VIP
//                if (sn.equals(member.getDevSn())) {
                // 该VIP用户租借的是可免费的机柜，那么开始计算其的优惠金额
                // 首先查询该VIP用户的租借次数

//                }
                if (member.getStoreId().equals(device.getStoreId())) {
                    // 该VIP用户租借的是可免费的门店，那么开始计算其的优惠金额
                    // 首先查询该VIP用户的租借次数
                    flag = true;
                }
            } else {
                flag = true;
            }
            if (flag) {
                // VIP对该机柜SN存在免费机会
                Integer dailyOrderLimit = member.getDailyOrderLimit(); // 每天免费订单数
                if (dailyOrderLimit > 0) {
                    // 查询该VIP用户今日已免费次数
                    Integer todayFreeCount = usedService.selectCountByTodayFree(appUser.getId());
                    if (todayFreeCount < dailyOrderLimit) {
                        // 今天用户已免费次数 小于等于 VIP用户的设置的免费次数
                        // 该用户可以免费试用充电线
                        JSONObject oneMeal = (JSONObject) array.get(0);
                        JSONObject responseOBJ = usedService.lineVipBorrow(appUser, device, oneMeal);
                        return BatteryJSONResult.build(3, "免费用户租借充电线", responseOBJ);
                    }
                }
            }
        }

        boolean needAuthPhone = false;
        if (StringUtils.isBlank(appUser.getMobile())) {
            Integer authPhoneNeedCount = Integer.parseInt(configService.selectConfigByKeyNoCache("sys.appuser.line.warrantphone"));
            if (authPhoneNeedCount >= 0) {
                // 查询该用户租借次数
                Integer borrowCount = usedService.selectBorrowCount(appUser.getId());
                if (borrowCount >= authPhoneNeedCount) {
                    // 用于需要授权手机号
                    needAuthPhone = true;
                }
            }
        }
        if (needAuthPhone) {
            responseObj.put("need_tel", 1);
            responseObj.put("need_tel_tip_1", configService.selectConfigByKeyNoCache("sys.authtel.but.line.tips")); // 页面上授权手机号按钮文字
            responseObj.put("refuse_msg", configService.selectConfigByKeyNoCache("sys.authtel.line.refuse_msg")); // 用户拒绝授权手机号的提示
            responseObj.put("refuse_show", Integer.parseInt(configService.selectConfigByKeyNoCache("sys.authtel.line.refuse_show"))); // 拒绝是否需要提示文字 1 为需要 0 为不需要
            responseObj.put("refuse_after_borrow", Integer.parseInt(configService.selectConfigByKeyNoCache("sys.authtel.line.refuse_after_borrow"))); // 拒绝之后是否可以继续租借 1 可以继续租借 0 不允许继续租借
        } else {
            responseObj.put("need_tel", 0);
        }
        responseObj.put("sn", sn);
        return BatteryJSONResult.ok(responseObj);
    }


    /**
     * 再次获取密码
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("againGetPwd")
    public BatteryJSONResult againGetPwd(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }

        String used_id = obj.getString("used_id");
        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("未查询到对应的租借订单，请联系客服");
        }
        Order order = orderService.selectByPrimaryKey(used.getTrueOrderId());
        String lineTime = order.getExtend();

        UsedBasics basics = usedBasicsService.selectByPrimaryKey(used_id);

        String password = usedService.getPwByNewLine(basics.getRentDeviceId(), lineTime);
        JSONObject requestJSON = new JSONObject();
        requestJSON.put("password", password);
        requestJSON.put("used_id", used_id);
        return BatteryJSONResult.ok(requestJSON);
    }


    /**
     * 租借充电线
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("LineBorrow")
    public BatteryJSONResult LineBorrow(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String sn = obj.getString("sn");
        String time = obj.getString("time");
        String order_id = obj.getString("order_id");
        BigDecimal amount = obj.getBigDecimal("amount");

        Device device = deviceService.selectBySn(sn);
        if (device == null) {
            return BatteryJSONResult.errorMsg("该设备未激活!");
        }

        if (StringUtils.isBlank(order_id)) {
            // 订单未创建
            JSONObject requestJSON = new JSONObject();
            requestJSON.put("sn", sn);
            requestJSON.put("amount", amount);
            requestJSON.put("time", time);
            return BatteryJSONResult.build(3, "未创建订单", requestJSON);
        }

        // 查询用户是否支付
        Order order = orderService.selectOrderById(order_id);
        if (order == null) {
            return BatteryJSONResult.errorMsg("查询不到对应的支付订单，请联系管理员");
        }

        if (!OrderTradeStateEnum.PAY_SUCCESS.getCode().equals(order.getTradeState())) {
            return BatteryJSONResult.errorMsg("订单未支付");
        }

        JSONObject responseOBJ = usedService.lineBorrow(order, appUser, device);
        return BatteryJSONResult.ok(responseOBJ);
    }


    /**
     * 微信用户授权手机号
     *
     * @param request
     * @param obj
     * @return
     */
    @PostMapping("getPhoneNumber")
    public BatteryJSONResult getPhoneNumber(HttpServletRequest request, @RequestBody JSONObject obj) {
        String openid = request.getHeader("openid");
        if (StringUtils.isBlank(openid)) {
            return BatteryJSONResult.errorMsg("发送错误，请退出程序，重新进去!");
        }
        AppUser appUser = appUserService.selectByOpenId(openid);
        if (appUser == null) {
            return BatteryJSONResult.errorMsg("您未授权，请先授权登录!");
        }
        String encryptedData = obj.getString("encryptedData");
        if (StringUtils.isBlank(encryptedData)) {
            return BatteryJSONResult.errorMsg("请授权手机号!");
        }
        String iv = obj.getString("iv");
        String sessionKey = appUser.getSessionKey();
        WxMaService wxService = WxMaConfiguration.getMaService(Constants.wxMinAppID);
        WxMaPhoneNumberInfo phoneNumberInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        if (phoneNumberInfo == null) {
            return BatteryJSONResult.errorMsg("授权手机号解析失败！");
        }
        String phone = phoneNumberInfo.getPhoneNumber();
        AppUser appUserUpdate = new AppUser();
        appUserUpdate.setId(appUser.getId());
        appUserUpdate.setMobile(phone);
        appUserService.updateByPrimaryKeySelective(appUserUpdate);
        return BatteryJSONResult.ok();
    }

}
